package com.whcoding.test.common;

import com.google.common.base.Joiner;
import com.whcoding.test.constant.BaseConstant;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @program: spring-boot-learning
 * @description:
 * @author: whcoding
 * @create: 2022-06-02 11:00
 **/
public class BasicStringUtils {

	/**
	 * 文本替换成*号
	 *
	 * @param str
	 * @param start 开始位置
	 * @param end   结束位置
	 * @return
	 */
	public static String replaceStar(String str, int start, int end) {
		int strLen;
		if ((str == null) || ((strLen = str.length()) == 0) || str.toLowerCase().equals("null"))
			return "";
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < strLen; ++i) {
			if (i < start) {
				sb.append(str.charAt(i));
			} else if (i <= end) {
				sb.append("*");
			} else {
				sb.append(str.charAt(i));
			}
		}
		return sb.toString();
	}


	/**
	 * 解决split函数的一个问题： 比如有个字符串String a =
	 * "a,b,c";那么a.split(",");返回的是一个String型的数组长度为3， 若字符串a = "a,,c"
	 * 执行a.split(",");返回的也是长度为3的字符串数组， 若a = "a,,"
	 * 执行a.split(",");此时返回的是个长度为1的字符串数组,把后面的就给去了， 如果程序中用到了后面的字符，就会引起数组越界的错误，
	 * 可以将a = "a,,"在加一个字符a = "a,,,end"，这样虽然改变了数组的长度但是不会产生数组越界的错误。
	 */
	public static String[] strSplit(String str) {
		if (StringUtils.isEmpty(str)) {
			return null;
		}
		if (',' == (str.charAt(str.length() - 1))) {
			str += ",END";
		}
		return str.split(",");
	}

	public static String[] strSplit(String str, int len) {
		if (StringUtils.isEmpty(str)) {
			return new String[len];
		}
		return strSplit(str);
	}


	/**
	 * 生成length位随机数
	 *
	 * @param length
	 * @return
	 */
	public static String getCharAndNumr(int length) {
		String val = "";
		Random random = new Random();
		for (int i = 0; i < length; i++) {
			// 输出字母还是数字
			String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
			// 字符串
			if ("char".equalsIgnoreCase(charOrNum)) {
				// 取得大写字母还是小写字母
				int choice = random.nextInt(2) % 2 == 0 ? 65 : 97;
				val += (char) (choice + random.nextInt(26));
				// 数字
			} else if ("num".equalsIgnoreCase(charOrNum)) {
				val += String.valueOf(random.nextInt(10));
			}
		}
		return val;
	}


	/**
	 * 对身份证，银行卡号的处理
	 *
	 * @param str
	 * @return
	 */
	public static String replcceStr(String str) {
		if (!StringUtils.isNotBlank(str)) {
			return null;
		} else {
			String pre = str.substring(0, 3);
			String suf = str.substring(str.length() - 4);
			return pre + "************" + suf;
		}
	}


	/**
	 * 去除空格
	 *
	 * @param str
	 * @return
	 */
	public static String trim(String str) {
		if (!StringUtils.isNotBlank(str)) {
			return null;
		} else {
			return str.replaceAll(" ", "");
		}
	}


	/**
	 * 全角转半角
	 *
	 * @param input
	 * @return
	 */
	public static String toHalfStr(String input) {
		char c[] = input.toCharArray();
		for (int i = 0; i < c.length; i++) {
			if (c[i] == '\u3000') {
				c[i] = ' ';
			} else if (c[i] > '\uFF00' && c[i] < '\uFF5F') {
				c[i] = (char) (c[i] - 65248);
			}
		}
		String returnString = new String(c);

		return returnString;
	}

	/**
	 * 半角转全角
	 *
	 * @param input
	 * @return
	 */
	public static String toFullStr(String input) {
		char c[] = input.toCharArray();
		for (int i = 0; i < c.length; i++) {
			if (c[i] == ' ') {
				// 采用十六进制,相当于十进制的12288
				c[i] = '\u3000';
			} else if (c[i] < '\177') {
				// 采用八进制,相当于十进制的127
				c[i] = (char) (c[i] + 65248);
			}
		}
		return new String(c);
	}

	/**
	 * 对用户输入进行清理$（美元符号） [5] %（百分比符号） [6] @（at 符号） [7] '（单引号） [8] "（引号） [9]
	 * \'（反斜杠转义单引号） [10] \"（反斜杠转义引号） [11] <>（尖括号） [12] ()（括号） [13] +（加号） [14]
	 * CR（回车符，ASCII 0x0d） [15] LF（换行，ASCII 0x0a） [16] ,（逗号） [17] \（反斜杠）
	 */
	public static String replaceStr(String str) {
		str = str.replace("'", "‘");
		str = str.replace("|", "｜");
		str = str.replace("&", "＆");
		str = str.replace(";", "；");
		str = str.replace("@", "＠");
		str = str.replace("\"", "”");
		str = str.replace("\\'", "＼’");
		str = str.replace("\\\"", "＼＼‘");
		str = str.replace("<", "《");
		str = str.replace(">", "》");
		str = str.replace("(", "（");
		str = str.replace(")", "）");
		str = str.replace("\\(", "（");
		str = str.replace("\\)", "）");
		str = str.replace("+", "＋");
		str = str.replace("\\+", "＋");
		str = str.replace("\r", "");
		str = str.replace("\n", "");
		str = str.replace("script", "　s　c　r　i　p　t　");
		str = str.replace("SCRIPT", "　s　c　r　i　p　t　");
		str = str.replace("%27", "");
		str = str.replace("%22", "");
		str = str.replace("%3E", "");
		str = str.replace("%3C", "");
		str = str.replace("%3D", "");
		str = str.replace("%2F", "");
		return str;
	}


	/**
	 * 驼峰命名法工具
	 *
	 * @return toCamelCase(" hello_world ") == "helloWorld"
	 * toCapitalizeCamelCase("hello_world") == "HelloWorld"
	 * toUnderScoreCase("helloWorld") = "hello_world"
	 */
	public static String toCamelCase(String s) {
		if (s == null) {
			return null;
		}
		s = s.toLowerCase();
		StringBuilder sb = new StringBuilder(s.length());
		boolean upperCase = false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);

			if (c == BaseConstant.SEPARATOR) {
				upperCase = true;
			} else if (upperCase) {
				sb.append(Character.toUpperCase(c));
				upperCase = false;
			} else {
				sb.append(c);
			}
		}
		return sb.toString();
	}

	/**
	 * 驼峰命名法工具
	 *
	 * @return toCamelCase(" hello_world ") == "helloWorld"
	 * toCapitalizeCamelCase("hello_world") == "HelloWorld"
	 * toUnderScoreCase("helloWorld") = "hello_world"
	 */
	public static String toCapitalizeCamelCase(String s) {
		if (s == null) {
			return null;
		}
		s = toCamelCase(s);
		return s.substring(0, 1).toUpperCase() + s.substring(1);
	}

	/**
	 * 驼峰命名法工具
	 *
	 * @return toCamelCase(" hello_world ") == "helloWorld"
	 * toCapitalizeCamelCase("hello_world") == "HelloWorld"
	 * toUnderScoreCase("helloWorld") = "hello_world"
	 */
	public static String toUnderScoreCase(String s) {
		if (s == null) {
			return null;
		}
		StringBuilder sb = new StringBuilder();
		boolean upperCase = false;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);

			boolean nextUpperCase = true;

			if (i < (s.length() - 1)) {
				nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
			}

			if ((i > 0) && Character.isUpperCase(c)) {
				if (!upperCase || !nextUpperCase) {
					sb.append(BaseConstant.SEPARATOR);
				}
				upperCase = true;
			} else {
				upperCase = false;
			}

			sb.append(Character.toLowerCase(c));
		}

		return sb.toString();
	}

	/**
	 * 首字母转小写
	 *
	 * @param s
	 * @return
	 */
	public static String toLowerCaseFirstOne(String s) {
		if (Character.isLowerCase(s.charAt(0))) {
			return s;
		} else {
			return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
		}
	}

	/**
	 * 首字母转大写
	 *
	 * @param s
	 * @return
	 */
	public static String toUpperCaseFirstOne(String s) {
		if (Character.isUpperCase(s.charAt(0))) {
			return s;
		} else {
			return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
		}
	}

	/**
	 * 去除字符串中头部和尾部所包含的空格（包括:空格(全角，半角)、制表符、换页符等）
	 *
	 * @param s
	 * @return
	 */
	public static String stringTrim(String s) {
		String result = "";
		if (null != s && !"".equals(s)) {
			result = s.replaceAll("^[　*| *| *|//s*]*", "").replaceAll("[　*| *| *|//s*]*$", "");
		}
		return result;
	}

	/**
	 *
	 * response.setHeader("Content-disposition", "attachment; filename="+toUtf8String("中文.xls"));
	 * 把字符串转成utf8编码，保证中文文件名不会乱码
	 *
	 * @param s
	 * @return
	 */
	public static String toUtf8String(String s) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (c >= 0 && c <= 255) {
				sb.append(c);
			} else {
				byte[] b;
				try {
					b = Character.toString(c).getBytes("utf-8");
				} catch (Exception ex) {
					System.out.println(ex);
					b = new byte[0];
				}
				for (int j = 0; j < b.length; j++) {
					int k = b[j];
					if (k < 0) {
						k += 256;
					}
					sb.append("%" + Integer.toHexString(k).toUpperCase());
				}
			}
		}
		return sb.toString();
	}

	/**
	 * 拼接String字符串
	 * @param str
	 * @return
	 */
	public static String resultStr(String str) {
		return String.format("%s", str);
	}

	public static String resultStr(String str1, String str2) {
		return String.format("%s %s", str1, str2);
	}

	public static String resultStr(String str1, String str2, String str3) {
		return String.format("%s %s %s", str1, str2, str3);
	}

	public static String resultStr(String... strs) {
		List<String> stringList = new ArrayList<>();
		for (int i = 0; i < strs.length; i++) {
			stringList.add(strs[i]);
		}
		return Joiner.on(" ").join(stringList);
	}

	public static String resultStrByArray(List<String> stringList) {
		return Joiner.on(" ").join(stringList);
	}

}
